#include <iostream>
#include <string>
#include <unordered_map>
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/TcpConnection.h>
#include <muduo/net/Buffer.h>

// server/client类负责发起各种任务，如 连接请求、发送数据、接收数据等
// 这些任务通常被封装成回调函数或其它任务类对象，然后提交给 EventLoop
// EventLoop 负责执行任务 —— 事件监听、任务调度、资源管理
// 即 eventloop 负责处理设置各种 连接事件回调函数 和 消息事件回调函数


class DictServer
{
private:
    void onConnection(const muduo::net::TcpConnectionPtr& conn)
    {
        if (conn->connected())
        {
            std::cout << "连接成功" << std::endl;
        }
        else
        {
            std::cout << "连接断开" << std::endl;
        }
    }

    void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf)
    {
        static std::unordered_map<std::string, std::string> dict{{"apple", "苹果"}, 
                                                {"happy", "开心的"}, 
                                                {"iterator", "迭代器"}};

        // std::string msg = conn->retrieveAllAsString();
        std::string msg = buf->retrieveAllAsString(); // 从缓冲区 Buffer 中读数据

        std::string res;
        if (dict.find(msg) != dict.end())
        {
            res = dict[msg];
        }
        else 
            res = "Not Found";
        
        conn->send(res);
    }
public:
    DictServer(uint16_t port)
        :_server(&_baseloop, muduo::net::InetAddress("0", port), "DictServer", muduo::net::TcpServer::kReusePort)
    {
        // 设置连接事件的回调函数
        _server.setConnectionCallback(std::bind(&DictServer::onConnection, this, std::placeholders::_1));

        // 设置消息事件的回调函数
        _server.setMessageCallback(std::bind(&DictServer::onMessage, this, std::placeholders::_1, std::placeholders::_2));
    }

    void Start()
    {
        _server.start(); // 开始监听连接
        _baseloop.loop(); // 开始事件循环
        // 在 loop 方法中，事件循环会不断监听并处理各种事件：
        // 当有新的连接请求时，会调用连接事件回调函数；
        // 当消息到达时，会调用消息事件回调函数
    }

private:
    muduo::net::EventLoop _baseloop; 
    muduo::net::TcpServer _server;
};


int main()
{
    DictServer server(8080);
    server.Start();

    return 0;
}